package com.dolawing.phonecallapp.listenphonecall;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.android.internal.telephony.ITelephony;
import com.dolawing.phonecallapp.MainActivity;
import com.dolawing.phonecallapp.R;
import com.dolawing.phonecallapp.blacknumber.db.BlackNumberDao;
import com.dolawing.phonecallapp.keepAliveUi.KeepManager;
import com.dolawing.phonecallapp.phoneLog.CallDetails;
import com.dolawing.phonecallapp.phoneLog.PhoneCallUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class MyPhoneBroadcastListener extends BroadcastReceiver {
    private Context mContext;
    private View phoneCallView;
    private TextView tvCallNumber;
    private Button btnOpenApp;

    private WindowManager windowManager;
    private WindowManager.LayoutParams params;

    private String callNumber;
    private boolean hasShown;
    private boolean isCallingIn;

    private BlackNumberDao blackNumberDao;

    /**
     * 手机没有通话，在一般的状态值
     */
    public static final int CALL_TYPE_IDEL = 0;
    /**
     * 手机通话状态值
     */
    public static final int CALL_TYPE_CALLING = 1;
    /**
     * 手机响铃状态值
     */
    public static final int CALL_TYPE_RING = 2;

    /**
     * 当前手机通话状态值
     */
    private int currentState = CALL_TYPE_IDEL ;
    /**
     * 手机原来的通话状态值
     */
    private int oldState = CALL_TYPE_IDEL ;

    /**
     * 数据库Helper类，只是帮助我们存取状态值，可以改成用文件流实现
     */
    private SqliteUtil sqlUtil = null;
    private MyPhoneListener listener;
    private Handler mHandler= null;

    @Override//当发生监听的事件，系统会调用这个方法
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        initPhoneCallView();
        //进行细节上的监控，我们需要操作TelephonyManager，为它设置监听器，他就给我们反馈
        //拿到系统的TelephonyManager
        listener = new MyPhoneListener();//创建监听器
        TelephonyManager tpManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (tpManager!=null){
            tpManager.listen( listener, PhoneStateListener.LISTEN_CALL_STATE);//设置监听器
        }
        sqlUtil = new SqliteUtil(mContext);
        blackNumberDao = new BlackNumberDao(mContext);
        mHandler = new Handler(Looper.getMainLooper());

    }

    private class MyPhoneListener extends PhoneStateListener {
        @Override//当电话状态发生改变的时候，系统会调用这个方法
        public void onCallStateChanged(int state, String incomingNumber) {
            //首先取得当前的状态值
            oldState = sqlUtil.getOldState();
            switch( state ){
                case TelephonyManager.CALL_STATE_IDLE :
                    currentState = CALL_TYPE_IDEL;
                    dismiss();
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK :
                    currentState = CALL_TYPE_CALLING;
                    updateUI();
                    show();
                    break;
                case TelephonyManager.CALL_STATE_RINGING :
                    currentState = CALL_TYPE_RING;
                    isCallingIn = true;

                    updateUI();
                    show();
                    break;
            }
            //当通话状态发生改变
            if(oldState == CALL_TYPE_RING && currentState == CALL_TYPE_CALLING ){
                Log.i("------>","接听");
                BroadcastUnRepeate.getInstance(mContext).setHasOffHook(false);
            } else if(oldState == CALL_TYPE_CALLING && currentState == CALL_TYPE_IDEL ){
                Log.i("------>", "挂断");
                BroadcastUnRepeate.getInstance(mContext).setHasOffHook(true);
                printLastCallLog();

            } else if (oldState == CALL_TYPE_IDEL && currentState == CALL_TYPE_IDEL
                    && BroadcastUnRepeate.getInstance(mContext).isHasOffHook()==false){
                Log.i("CALL_STATE_IDLE--->","取消");
                BroadcastUnRepeate.getInstance(mContext).setHasOffHook(true);
                printLastCallLog();
            }else if (oldState == CALL_TYPE_RING && currentState == CALL_TYPE_RING
                    &&BroadcastUnRepeate.getInstance(mContext).getCallRing() == 1){
                BroadcastUnRepeate.getInstance(mContext).setCallRing(0);
                BroadcastUnRepeate.getInstance(mContext).setHasOffHook(false);
                Log.i("CALL_STATE_IDLE--->","响铃");

                boolean isBlackNumber = blackNumberDao.isBlackNumber(incomingNumber);
                if(isBlackNumber){
                    Log.i("--->isBlackNumber",String.valueOf(isBlackNumber));
                    endCall2(incomingNumber);
                    return;
                }
            }
            if(oldState == CALL_TYPE_IDEL && currentState == CALL_TYPE_CALLING ){
                Log.i("------>", "拨号");
                BroadcastUnRepeate.getInstance(mContext).setHasOffHook(false);
            }
            sqlUtil.updateState(currentState);

        }
    }

    private void printLastCallLog(){
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                CallDetails callDetail = PhoneCallUtils.getLastOneCallDetails(mContext);
                Log.i("最后一通电话",callDetail.toString());
                Toast.makeText(mContext,callDetail.toString(),Toast.LENGTH_LONG).show();

                BroadcastUnRepeate.getInstance(mContext).setCallIdle(1);
                BroadcastUnRepeate.getInstance(mContext).setCallRing(1);
                BroadcastUnRepeate.getInstance(mContext).setCallOffHook(1);

            }
        },1000);
    }

    private void initPhoneCallView() {
        windowManager = (WindowManager) mContext.getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE);
        int width = windowManager.getDefaultDisplay().getWidth();
        int height = windowManager.getDefaultDisplay().getHeight();

        params = new WindowManager.LayoutParams();
        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.width = width;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

        // 设置图片格式，效果为背景透明
        params.format = PixelFormat.TRANSLUCENT;
        // 设置 Window flag 为系统级弹框 | 覆盖表层
        params.type = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
        //  WindowManager.LayoutParams.TYPE_PHONE;

        // 不可聚集（不响应返回键）| 全屏
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_FULLSCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        // API 19 以上则还可以开启透明状态栏与导航栏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            params.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        }

        FrameLayout interceptorLayout = new FrameLayout(mContext) {

            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {

                        return true;
                    }
                }

                return super.dispatchKeyEvent(event);
            }
        };

        phoneCallView = ((LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.view_phone_call, interceptorLayout);
        tvCallNumber = phoneCallView.findViewById(R.id.tv_call_number);
        btnOpenApp = phoneCallView.findViewById(R.id.btn_open_app);
        btnOpenApp.setOnClickListener(v -> {
            Intent intent = new Intent(mContext.getApplicationContext(), MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        });
    }


    /**
     * 显示顶级弹框展示通话信息
     */
    private void show() {
        if (!hasShown) {
            windowManager.addView(phoneCallView, params);
            hasShown = true;
        }
    }

    /**
     * 取消显示
     */
    private void dismiss() {
        if (hasShown) {
            windowManager.removeView(phoneCallView);
            isCallingIn = false;
            hasShown = false;
        }
    }

    private void updateUI() {
        tvCallNumber.setText(formatPhoneNumber(callNumber));

        int callTypeDrawable = isCallingIn ? R.drawable.ic_phone_call_in : R.drawable.ic_phone_call_out;
        tvCallNumber.setCompoundDrawablesWithIntrinsicBounds(null, null,
                mContext.getResources().getDrawable(callTypeDrawable), null);
    }

    public static String formatPhoneNumber(String phoneNum) {
        if (!TextUtils.isEmpty(phoneNum) && phoneNum.length() == 11) {
            return phoneNum.substring(0, 3) + "-"
                    + phoneNum.substring(3, 7) + "-"
                    + phoneNum.substring(7);
        }
        return phoneNum;
    }

    //挂断电话 2
    private void endCall2(String phone) {
        boolean flag = false;//判断是否拦截成功
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            TelecomManager manager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
            if (manager != null) {
                if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(mContext.getApplicationContext(),"没有权限，拦截失败！",Toast.LENGTH_SHORT).show();
                }
                flag = manager.endCall();
            }
        }else {
            //ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
            try {
                //获取类
                @SuppressLint("PrivateApi")
                Class<?> serviceManager = Class.forName("android.os.ServiceManager");
                //获取方法
                Method getService = serviceManager.getMethod("getService", String.class);
                //使用方法
                IBinder invoke = (IBinder) getService.invoke(null, Context.TELEPHONY_SERVICE);
                ITelephony iTelephony = ITelephony.Stub.asInterface(invoke);
                assert iTelephony != null;
//                if("10086".equals(phone)){
//                    flag = iTelephony.endCall();//挂断电话
//                    Toast.makeText(getApplicationContext(),"方法二：28版本以下：10086被拦截！",Toast.LENGTH_SHORT).show();
//                }
                flag = iTelephony.endCall();//挂断电话
            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | RemoteException e) {
                e.printStackTrace();
            }
        }
    }
}
